package com.ruoyi.auth.controller;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.auth.config.WxAppConfig;
import com.ruoyi.auth.form.WxLoginBody;
import com.ruoyi.auth.form.WxPhoneBody;
import com.ruoyi.auth.form.WxRegisterBody;
import com.ruoyi.auth.service.SysLoginService;
import com.ruoyi.auth.service.wechat.WechatHelper;
import com.ruoyi.auth.utils.LoginUtils;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.MD5Utils;
import com.ruoyi.common.core.utils.ObjectUtil;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.domain.WxUser;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.api.model.UserDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/wechat")
public class WxTokenController {
    // 日志记录
    private static final Logger logger = LoggerFactory.getLogger(TokenController.class);

    @Autowired
    private SysLoginService sysLoginService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private WxAppConfig wxAppConfig;
    // 给远程调用。。。
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisService redisService;

    /**
     * 微信授权登录
     *
     * @param wxLoginBody
     * @return
     */
    @PostMapping("/login")
    public R<?> login(@RequestBody WxLoginBody wxLoginBody) {

        String appId = wxAppConfig.getAppId();
        String appSecret = wxAppConfig.getAppSecret();
        if ("收回莱".equalsIgnoreCase(wxLoginBody.getAppName())) {
            appId = "wx99fdb9888ec979d0";
            appSecret = "0c363f07fe0f2173cb4c7b4802b1e4fc";
        }

        if ("student".equals(wxLoginBody.getAppName()) || "石马河七龙珠".equals(wxLoginBody.getAppName()) ) {
            appId = "wxaec42aee231e10ed";
            appSecret = "6ded20d48d780caf377367b5c04f35b1";
        }
        if (StringUtils.isEmpty(wxLoginBody.getAppName()) || "".equals(wxLoginBody.getAppName())) {
            appId = "wx2670131776e09df2";
            appSecret = "0036c66ca7db34b4e3fa87cea757c7f6";
        }


        logger.info("登录参数: " + JSONObject.toJSONString(wxLoginBody));
        // 获取登录凭证 只能用一次
        String code = wxLoginBody.getCode();
        // 向微信服务器发送请求获取用户信息
        // 1. 调用小程序登录接口
        WechatHelper helper = new WechatHelper();

        System.out.println("当前登录的 appId     " + appId + " ==========appSecret =====" + appSecret + "                 openid 是 ==========");

        String openId = helper.getOpenId(restTemplate, appId, appSecret, code);
        if (openId == null || openId.length() == 0) {
            System.out.println("------------------------获取微信用户信息失败---------------------------------");
            return R.fail("获取微信用户信息失败");
        }
        System.out.println("当前登录的 appId" + appId + " ==========appSecret =====" + appSecret + "             openid 是 ==========" + openId);
        String accessToken = helper.getAccountToken(restTemplate, redisService, appId, appSecret);

        if ("student".equals(wxLoginBody.getUserType())) {
            LoginUser userInfo = sysLoginService.wxLogin(openId, wxLoginBody);
            userInfo.setOpenid(openId);
            userInfo.setPhone(userInfo.getSysUser().getPhonenumber() == null ? "" : userInfo.getSysUser().getPhonenumber());
            Map<String, Object> map = tokenService.createToken(userInfo);
            map.put("access_token", accessToken);
            map.put("userInfo", userInfo);
            return R.ok(map);
        } else {
            JSONObject userInfoJson = new JSONObject();
            userInfoJson.put("access_token", accessToken);
            userInfoJson.put("openid", openId);
            System.out.println(userInfoJson.toString());
            return R.ok(userInfoJson);
        }

    }


    @PostMapping("/register")
    public R<?> register(@RequestBody WxRegisterBody wxRegisterBody) {
        //判断本地有没有，没有就存入到数据库中。
        System.out.println(wxRegisterBody.toString());
        return R.fail("微信登录失败！");
    }
/*

    @PostMapping("/user/info")
    public R<?> userinfo(@RequestBody String openid) {
// # 1. 获取 access_token
//        url = f'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}'
//
//                # 2. 获取用户信息
//                url = f'https://api.weixin.qq.com/cgi-bin/user/info?access_token={access_token}&openid={openid}&lang=zh_CN'
        return R.fail("微信登录失败！");
    }
*/


    /**
     * 获取用户手机号
     *
     * @param wxPhoneBody POST https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=ACCESS_TOKEN
     */
    @PostMapping("/getPhoneNumber")
    public R<?> getPhoneNumber(@RequestBody @Validated WxPhoneBody wxPhoneBody) {
        System.out.println(" =======================================================获取手机号码=====================================================================");
        System.out.println(wxPhoneBody.getAccessToken());
        System.out.println(" =======================================================获取手机号码=====================================================================");
        System.out.println(wxPhoneBody.toString());
        System.out.println("获取手机号码手机需要的参数是getPhoneNumber  access_token ,  这个code前端获得  openid   +请求微信最后返回结果=111==============================");

        if (StringUtils.isEmpty(wxPhoneBody.getOpenid()) || StringUtils.isEmpty(wxPhoneBody.getPhoneCode())) {
            return R.fail("openid 或者 phonecode 为空");
        }

        String responseBody = "";
        String phone = "";


        String dataSourceHash = StringUtils.isNotBlank(wxPhoneBody.getDataSource())
                ? MD5Utils.md5(wxPhoneBody.getDataSource())
                : "default";
        String redisKey ="phone" +wxPhoneBody.getIdentity()+  dataSourceHash+"_"+wxPhoneBody.getOpenid();
        Map<String, List<String>> keyValue = redisService.getKeyValue(redisKey);
        System.out.println("查看从redis中获取的 keyValue" + keyValue);
        if ( keyValue == null || keyValue.isEmpty() || ObjectUtil.isEmpty(keyValue)) {
//           redis中如果没有 改成 从数据库中拿 ，数据库中也没有 再从 腾讯拿
//            UserDto userDto = new UserDto();
//            userDto.setOpenid(wxPhoneBody.getOpenid());
//            wxUser =sysLoginService.getUser(userDto);

            responseBody = LoginUtils.decryptPhoneNumber(wxPhoneBody.getAccessToken(), wxPhoneBody.getPhoneCode(), restTemplate);
            if (responseBody.contains("phoneNumber")) {
                System.out.println("55555555555555555555");
                JSONObject phoneResultBody = JSONObject.parseObject(responseBody);
                String phone_info = phoneResultBody.getString("phone_info");
                JSONObject phoneInfoResultBody = JSONObject.parseObject(phone_info);
                phone = phoneInfoResultBody.getString("phoneNumber");
                phone = phone.replaceAll("\"", "").replaceAll("\\[", "").replaceAll("\\]", "");
            }
            if (StringUtils.isNotEmpty(phone)) {
                System.out.println("6666666666666666666666666666");
                phone = phone.replaceAll("\"", "").replaceAll("\\[", "").replaceAll("\\]", "");

                System.out.println("要把手机号码 和 phone 存到  sysuser表 解密手机号码成功    " + phone);
//
                redisService.setCacheObject( redisKey, phone, 48L, TimeUnit.HOURS);
            }
        } else {
            System.out.println(" redis不为空情况 7777777777777777777777  拿redis 的key ");
            phone = String.valueOf(keyValue.get( redisKey    ));
        }
        phone = phone.replaceAll("\"", "").replaceAll("\\[", "").replaceAll("\\]", "");

        if (!responseBody.contains("失败") && StringUtils.isNotEmpty(phone)) {

            WxUser userInfo = sysLoginService.wxLogin(phone, wxPhoneBody  );
            userInfo.setIdentity(wxPhoneBody.getIdentity() );
            System.out.println("返回的用户信息是WxUser****************************");
            System.out.println(userInfo);


            LoginUser loginUser = new LoginUser();

            SysUser sysUser = new SysUser();
            sysUser.setUserId(userInfo.getUserId());
            sysUser.setUserName(userInfo.getUserName());
            sysUser.setIdentity(wxPhoneBody.getIdentity()  );
            sysUser.setDataSource(wxPhoneBody.getDataSource());
            loginUser.setSysUser(sysUser);
            loginUser.setPhone( sysUser.getPhonenumber());

            Map<String, Object> map = tokenService.createToken(loginUser);
            map.put("userInfo", userInfo);

            System.out.println("==========================返回结果==查看绿链的token===========================");

            System.out.println(map.toString());
            System.out.println("=========================从用户中获得的 token===========================");

            System.out.println(SecurityUtils.getToken());
            System.out.println("=========================创建token 的user===========================");
            System.out.println(loginUser.toString());

            return R.ok(map, "SUCCESS");
        } else {// 解析失败，返回错误信息

            System.out.println("7解析失败，返回错误信息999999999999999999");
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode rootNode = null;
            try {
                rootNode = objectMapper.readTree(responseBody);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                return R.fail(responseBody);
            }
            JsonNode msgNode = rootNode.path("errmsg");
            // 去掉转义字符
            String msg = msgNode.asText();
            return R.fail(msg);
        }
    }


    /**
     * 获取用户手机号
     *
     * @param wxPhoneBody POST https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=ACCESS_TOKEN
     */
    @PostMapping("/only/getPhoneNumber")
    public R<String> ogetPhoneNumber(@RequestBody @Validated WxPhoneBody wxPhoneBody) {
        System.out.println(" =======================================================获取手机号码=====================================================================");
        System.out.println(wxPhoneBody.toString());

        if (StringUtils.isEmpty(wxPhoneBody.getOpenid()) || StringUtils.isEmpty(wxPhoneBody.getPhoneCode())) {
            return R.fail("openid 或者 phonecode 为空");
        }

        String appId = "wxaec42aee231e10ed";
        String appSecret = "6ded20d48d780caf377367b5c04f35b1";
        String responseBody = "";
        String phone = "";

        WechatHelper helper = new WechatHelper();
        String accessToken = helper.getAccountToken(restTemplate, redisService, appId, appSecret);
        if (accessToken != null && !accessToken.isEmpty()) {
            System.out.println(accessToken);
            responseBody = LoginUtils.decryptPhoneNumber(accessToken, wxPhoneBody.getPhoneCode(), restTemplate);
            if (responseBody.contains("phoneNumber")) {
                JSONObject phoneResultBody = JSONObject.parseObject(responseBody);
                String phone_info = phoneResultBody.getString("phone_info");
                JSONObject phoneInfoResultBody = JSONObject.parseObject(phone_info);
                phone = phoneInfoResultBody.getString("phoneNumber");
                phone = phone.replaceAll("\"", "").replaceAll("\\[", "").replaceAll("\\]", "");
            }
            if (StringUtils.isNotEmpty(phone)) {
                phone = phone.replaceAll("\"", "").replaceAll("\\[", "").replaceAll("\\]", "");
                System.out.println("----" + phone);
                return R.ok(phone, "SUCCESS");
            } else {
                return R.fail("手机号获取失败");
            }
        } else {// 解析失败，返回错误信息
            return R.fail("会话已失效");
        }
    }


//    https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html
}
